package org.mcflier.appuntamento.data.model;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.mcflier.appuntamento.data.model.abstracts.AbstractMovie;
import org.mcflier.appuntamento.i18n.Country;
import org.mcflier.appuntamento.i18n.Language;

public class Movie extends AbstractMovie {

	private String id, originalName, overview, tagline, posterPath, homepage;
	private Date releaseDate;
	private int runtime;
	private boolean traced;
	private AlternativeTitle alternativeName;
	private boolean tracing;
	private String addingSource;
	private Timestamp addedDate;
	private Language tracingLanguage;
	private Timestamp tracedDate;
	private String downloadLink;
	private String tracedSource;
	
	private List<Production> productions;
	private List<Genre> genres;
	private List<Country> productionCountries;
	
	public Movie(String id, String originalName) {
		super(id, originalName);
		
		this.overview = null;
		this.tagline = null;
		this.posterPath = null;
		this.homepage = null;
		this.releaseDate = null;
		this.traced = false;
		this.alternativeName = null;
		this.tracing = false;
		this.addingSource = null;
		this.addedDate = null;
		this.tracingLanguage = null;
		this.tracedDate = null;
		this.downloadLink = null;
		this.tracedSource = null;
		
		this.productions = new ArrayList<Production>();
		this.genres = new ArrayList<Genre>();
		this.productionCountries = new ArrayList<Country>();
	}

	@Override
	public String getId() {
		return this.id;
	}

	@Override
	protected void setId(String id) {
		this.id = id;
	}

	@Override
	public String getOriginalName() {
		return this.originalName;
	}

	@Override
	public void setOriginalName(String originalName) {
		this.originalName = originalName;
	}

	@Override
	public AlternativeTitle getAlternativeName() {
		return this.alternativeName;
	}

	@Override
	public void setAlternativeName(AlternativeTitle alternativeName) {
		this.alternativeName = alternativeName;
	}

	@Override
	public String getOverview() {
		return this.overview;
	}

	@Override
	public void setOverview(String overview) {
		this.overview = overview;
	}

	@Override
	public String getHomepage() {
		return this.homepage;
	}

	@Override
	public void setHomepage(String homepage) {
		this.homepage = homepage;
	}

	@Override
	public String getTagline() {
		return this.tagline;
	}

	@Override
	public void setTagline(String tagline) {
		this.tagline = tagline;
	}

	@Override
	public String getPosterPath() {
		return this.posterPath;
	}

	@Override
	public void setPosterPath(String posterPath) {
		this.posterPath = posterPath;
	}

	@Override
	public Date getReleaseDate() {
		return this.releaseDate;
	}

	@Override
	public void setReleaseDate(Date releaseDate) {
		this.releaseDate = releaseDate;
	}

	@Override
	public int getRuntime() {
		return this.runtime;
	}

	@Override
	public void setRuntime(int runtime) {
		if(runtime<0)
			throw new IllegalArgumentException("Movie: Runtime must be equal or greater than zero");
		
		this.runtime = runtime;
	}

	@Override
	public boolean isTracing() {
		return this.tracing;
	}

	@Override
	public void setTracing(boolean tracing) {
		this.tracing = tracing;
	}

	@Override
	public String getAddedBy() {
		return this.addingSource;
	}

	@Override
	public void setAddedBy(String addingSource) {
		this.addingSource = addingSource;
	}

	@Override
	public Timestamp getAddedDate() {
		return this.addedDate;
	}

	@Override
	public void setAddedDate(Timestamp date) {
		this.addedDate = date;
	}

	@Override
	public Language getTracingLanguage() {
		return this.tracingLanguage;
	}

	@Override
	public void setTracingLanguage(Language language) {
		this.tracingLanguage = language;
	}

	@Override
	public boolean isTraced() {
		return this.traced;
	}

	@Override
	public void setTraced(boolean traced) {
		this.traced = traced;
	}

	@Override
	public Timestamp getTracedDate() {
		return this.tracedDate;
	}

	@Override
	public void setTracedDate(Timestamp date) {
		this.tracedDate = date;
	}

	@Override
	public String getTracedSource() {
		return this.tracedSource;
	}

	@Override
	public void setTracedSource(String tracedSource) {
		this.tracedSource = tracedSource;
	}

	@Override
	public String getDownloadLink() {
		return this.downloadLink;
	}

	@Override
	public void setDownloadLink(String link) {
		this.downloadLink = link;
	}

	@Override
	public void addProduction(Production production) {
		if(production == null)
			throw new NullPointerException("Movie: The adding production must not be null");
		
		if(this.getProduction(production.getId())==null)
			this.productions.add(production);
	}

	@Override
	public Production getProduction(int id) {
		for (Production production : this.productions) {
			if(production.getId() == id)
				return production;
		}
		
		return null;
	}

	@Override
	public Production getProduction(String name) {
		for (Production production : this.productions) {
			if(production.getName().equalsIgnoreCase(name.trim()))
				return production;
		}
		
		return null;
	}
	
	@Override
	public List<Production> getProductions() {
		return this.productions;
	}

	@Override
	public Production removeProduction(int id) {
		Production production = this.getProduction(id);
		if(production == null) return null;
		else
			if(this.productions.remove(production))
				return production;
			else
				return null;
	}

	@Override
	public void removeAllProductions() {
		this.productions.clear();
	}

	@Override
	public void addGenre(Genre genre) {
		if(genre == null)
			throw new NullPointerException("Movie: Adding genre must not be null");
		
		if(this.getGenre(genre.getId()) == null)
			this.genres.add(genre);
	}

	@Override
	public Genre getGenre(int id) {
		for (Genre genre : this.genres) {
			if(genre.getId() == id)
				return genre;
		}
		
		return null;
	}
	
	@Override
	public List<Genre> getGenres() {
		return this.genres;
	}

	@Override
	public Genre removeGenre(int id) {
		Genre genre = this.getGenre(id);
		
		if(genre == null)
			return null;
		else
			if(this.genres.remove(genre))
				return genre;
			else return null;
	}

	@Override
	public void removeAllGenres() {
		this.genres.clear();
	}

	@Override
	public void addProductionCountry(Country country) {
		if(country == null)
			throw new NullPointerException("Movie: Adding production country must not be null");
		
		if(this.getProductionCountry(country.getCode()) == null)
			this.productionCountries.add(country);
	}

	@Override
	public Country getProductionCountry(String code) {
		for (Country country : this.productionCountries) {
			if(country.getCode().equalsIgnoreCase(code))
				return country;
		}
		
		return null;
	}
	
	@Override
	public List<Country> getProductionCountries() {
		return this.productionCountries;
	}

	@Override
	public Country removeProductionCountry(String code) {
		Country country = this.getProductionCountry(code);
		
		if(country == null)
			return null;
		else
			if(this.productionCountries.remove(country))
				return country;
			else
				return null;
	}

	@Override
	public void removeAllProductionCountries() {
		this.productionCountries.clear();
	}
	
	public String toString(){
		return this.getId()+" "+this.getOriginalName();
	}
}